from selenium.common.exceptions import (
    ElementNotVisibleException,
    StaleElementReferenceException,
    TimeoutException
)
from functools import wraps
import time

class SmartExceptionHandler:
    """智能异常处理装饰器"""
    
    @classmethod
    def retry_on_failure(cls, func, max_attempts=3, delay=1):
        """重试装饰器
        
        Args:
            func: 被装饰的方法
            max_attempts: 最大重试次数
            delay: 重试延迟(秒)
        """
        @wraps(func)
        def wrapped(*args, **kwargs):
            last_exception = None
            for attempt in range(1, max_attempts + 1):
                try:
                    return func(*args, **kwargs)
                except (ElementNotVisibleException, 
                       StaleElementReferenceException,
                       TimeoutException) as e:
                    last_exception = e
                    if attempt == max_attempts:
                        break
                    args[0].log.warning(
                        f"Attempt {attempt}/{max_attempts} failed: {str(e)}"
                    )
                    time.sleep(delay * attempt)  # 指数退避
                    if hasattr(args[0], 'refresh'):
                        args[0].refresh()
            raise type(last_exception)(
                f"Failed after {max_attempts} attempts. Last error: {str(last_exception)}"
            )
        return wrapped